#ifndef _MELPEAK_H
#define _MELPEAK_H

#include <cmath>
#include "rsrfft.h"

#include <iostream>
using namespace std;

#define FEAT_TYPE "MELPEAK"
#define SUBBAND_NUM 12
#define ZERO_PADDING_RATE 0.9
#define SAMPLERATE 8000//16000
#define LO_FREQ 220.
#define HI_FREQ 4000.
#define RATIO_TH 0.6065
#define FEATURE_DIM 12
#define PI 3.1415926
#define SEMI_LOWER pow(2, -1.0/12.0)
//#define WHOLE_WIDTH pow(2, 1.0/12.0)-SEMI_LOWER
#define WHOLE_WIDTH (pow(2, 1.0/12.0)-SEMI_LOWER)	//  [11/22/2010 Song]

class MelPeak
{
public:
	MelPeak(unsigned long lenArg);
	~MelPeak();
	int CalcHeightWidth(short *buffer);

	// results
	float avgHeight[FEATURE_DIM];
	float avgWidth[FEATURE_DIM];
	float dctOpt[FEATURE_DIM]; // first six: Height, last six: Width

protected:
	int PickPeak(float *seq, unsigned long len, unsigned long *peakIdx, unsigned long &peakNum);
	float IsObviousPeak(float *seq, unsigned long *peakIdx, unsigned long peakNum, unsigned long idx);
	int Alternative(float *X, unsigned long sbdIdx);	
	
	float FFT2Mel(float k);
	float Freq2Mel(float f);

	void plotFFT(float *buffer, unsigned long N);

	SplitRadixFFT *fft;
	unsigned long len;
	float *hamWin;
	unsigned long fftSize;
	short fftOrder;
	unsigned long bndTab[SUBBAND_NUM];
	unsigned long sbdSize[SUBBAND_NUM];
};

class MelPeak_Feature
{
public:
	MelPeak_Feature(short *song, unsigned long lenArg, unsigned long winSize, unsigned long hopSize, int &nFrameNum);
	MelPeak_Feature(short *song, unsigned long lenArg, unsigned long winSize, unsigned long hopSize, bool *bAct, int &nThrow);
	~MelPeak_Feature();
	int Normalize(float* seq, unsigned long lenArg);
	int Normalize(float* seq, unsigned long lenArg, bool *bAct);	//  [11/19/2010 Song]
	int DCT(float *avgHeight, float *avgWidth, unsigned long frmNum);

	float *avgHeight; // [DIM1: 1-frameNum | DIM2: 1-frameNum | ... | ...]
	float *avgWidth;
	float *dctOpt; // [frame1: DIM1 DIM2 ... DIM12 |frame2: DIM1 DIM2 ... DIM12 | ... | ...]
};

#endif